home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / sun4c.md / fpu_simulator.c < prev    next >
C/C++ Source or Header  |  1989-08-17  |  6KB  |  239 lines

  1. #ifdef sccsid
  2. static char    sccsid[] = "@(#)fpu_simulator.c 1.8 88/02/08 SMI";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988 by Sun Microsystems, Inc.
  7.  */
  8.  
  9. /* Main procedures for Sparc FPU simulator. */
  10.  
  11. /*
  12.  * This whole file refuses to lint.
  13.  */
  14. #ifndef lint
  15. #include <sun4/fpu/fpu_simulator.h>
  16. #include <sun4/fpu/globals.h>
  17. #include <sys/signal.h>
  18.  
  19. /* PUBLIC FUNCTIONS */
  20.  
  21. PRIVATE enum ftt_type
  22. _fp_fpu_simulator(inst, pfsr)
  23.     fp_inst_type inst;    /* FPU instruction to simulate. */
  24.     fsr_type    *pfsr;    /* Pointer to image of FSR to read and write. */
  25.  
  26. {
  27.     unpacked    us1, us2, ud;    /* Unpacked operands and result. */
  28.     unsigned    nrs1, nrs2, nrd;    /* Register number fields. */
  29.     fsr_type    fsr;
  30.     unsigned    usr;
  31.     unsigned    andexcep;
  32.  
  33.     nrs1 = inst.rs1;
  34.     nrs2 = inst.rs2;
  35.     nrd = inst.rd;
  36.     _fp_current_exceptions = 0;    /* Initialize current exceptions. */
  37.     fsr = *pfsr;
  38.     fp_direction = fsr.rd;    /* Obtain rounding direction. */
  39.     fp_precision = fsr.rp;    /* Obtain rounding direction. */
  40.     switch (inst.opcode) {
  41.     case fmovs:
  42.         _fp_unpack_word(&usr, nrs2);
  43.         _fp_pack_word(&usr, nrd);
  44.         break;
  45.     case fabss:
  46.         _fp_unpack_word(&usr, nrs2);
  47.         usr &= 0x7fffffff;
  48.         _fp_pack_word(&usr, nrd);
  49.         break;
  50.     case fnegs:
  51.         _fp_unpack_word(&usr, nrs2);
  52.         usr ^= 0x80000000;
  53.         _fp_pack_word(&usr, nrd);
  54.         break;
  55.     case fadd:
  56.         _fp_unpack(&us1, nrs1, inst.prec);
  57.         _fp_unpack(&us2, nrs2, inst.prec);
  58.         _fp_add(&us1, &us2, &ud);
  59.         _fp_pack(&ud, nrd, inst.prec);
  60.         break;
  61.     case fsub:
  62.         _fp_unpack(&us1, nrs1, inst.prec);
  63.         _fp_unpack(&us2, nrs2, inst.prec);
  64.         _fp_sub(&us1, &us2, &ud);
  65.         _fp_pack(&ud, nrd, inst.prec);
  66.         break;
  67.     case fmul:
  68.         _fp_unpack(&us1, nrs1, inst.prec);
  69.         _fp_unpack(&us2, nrs2, inst.prec);
  70.         _fp_mul(&us1, &us2, &ud);
  71.         _fp_pack(&ud, nrd, inst.prec);
  72.         break;
  73.     case fdiv:
  74.         _fp_unpack(&us1, nrs1, inst.prec);
  75.         _fp_unpack(&us2, nrs2, inst.prec);
  76.         _fp_div(&us1, &us2, &ud);
  77.         _fp_pack(&ud, nrd, inst.prec);
  78.         break;
  79.     case fcmp:
  80.         _fp_unpack(&us1, nrs1, inst.prec);
  81.         _fp_unpack(&us2, nrs2, inst.prec);
  82.         fsr.fcc = _fp_compare(&us1, &us2, 0);
  83.         break;
  84.     case fcmpe:
  85.         _fp_unpack(&us1, nrs1, inst.prec);
  86.         _fp_unpack(&us2, nrs2, inst.prec);
  87.         fsr.fcc = _fp_compare(&us1, &us2, 1);
  88.         break;
  89.     case fsqrt:
  90.         _fp_unpack(&us1, nrs2, inst.prec);
  91.         _fp_sqrt(&us1, &ud);
  92.         _fp_pack(&ud, nrd, inst.prec);
  93.         break;
  94.     case ftoi:
  95.         _fp_unpack(&us1, nrs2, inst.prec);
  96.         fp_direction = fp_tozero;
  97.         /* Force rounding toward zero. */
  98.         _fp_pack(&us1, nrd, fp_op_integer);
  99.         break;
  100.     case ftos:
  101.         _fp_unpack(&us1, nrs2, inst.prec);
  102.         _fp_pack(&us1, nrd, fp_op_single);
  103.         break;
  104.     case ftod:
  105.         _fp_unpack(&us1, nrs2, inst.prec);
  106.         _fp_pack(&us1, nrd, fp_op_double);
  107.         break;
  108.     case ftox:
  109.         _fp_unpack(&us1, nrs2, inst.prec);
  110.         _fp_pack(&us1, nrd, fp_op_extended);
  111.         break;
  112.     default:
  113.         return (ftt_unimplemented);
  114.     }
  115.  
  116.     fsr.cexc = _fp_current_exceptions;
  117.     if (_fp_current_exceptions) {    /* One or more exceptions occurred. */
  118.         andexcep = _fp_current_exceptions & fsr.tem;
  119.         if (andexcep != 0) {    /* Signal an IEEE SIGFPE here. */
  120.             if (andexcep & (1 << fp_invalid))
  121.                 fptrapcode = FPE_FLTOPERR_TRAP;
  122.             else if (andexcep & (1 << fp_overflow))
  123.                 fptrapcode = FPE_FLTOVF_TRAP;
  124.             else if (andexcep & (1 << fp_underflow))
  125.                 fptrapcode = FPE_FLTUND_TRAP;
  126.             else if (andexcep & (1 << fp_division))
  127.                 fptrapcode = FPE_FLTDIV_TRAP;
  128.             else if (andexcep & (1 << fp_inexact))
  129.                 fptrapcode = FPE_FLTINEX_TRAP;
  130.             else
  131.                 fptrapcode = 0;
  132.             *pfsr = fsr;
  133.             return (ftt_ieee);
  134.         } else {    /* Just set accrued exception field. */
  135.             fsr.aexc |= _fp_current_exceptions;
  136.         }
  137.     }
  138.     *pfsr = fsr;
  139.     return (ftt_none);
  140. }
  141.  
  142. enum ftt_type
  143. fpu_simulator(pinst, pfsr)
  144.     fp_inst_type    *pinst;    /* Pointer to FPU instruction to simulate. */
  145.     fsr_type    *pfsr;    /* Pointer to image of FSR to read and write. */
  146.  
  147. /*
  148.  * fpu_simulator simulates FPU instructions only; reads and writes FPU data
  149.  * registers directly.
  150.  */
  151. {
  152.     union {
  153.         int        i;
  154.         fp_inst_type    inst;
  155.     }        kluge;
  156.     enum ftt_type    ftt;
  157.  
  158.     fptrapaddr = (char *) pinst;    /* bad inst addr in case we trap */
  159.     _fp_current_read_freg = _fp_read_pfreg;
  160.     _fp_current_write_freg = _fp_write_pfreg;
  161.     ftt = _fp_read_word((caddr_t) pinst, &(kluge.i));
  162.     if (ftt != ftt_none)
  163.         return (ftt);
  164.     return _fp_fpu_simulator(kluge.inst, pfsr);
  165. }
  166.  
  167. enum ftt_type
  168. fp_emulator(pinst, pregs, pwindow, pfpu)
  169.     fp_inst_type    *pinst;    /* Pointer to FPU instruction to simulate. */
  170.     struct regs    *pregs;    /* Pointer to PCB image of registers. */
  171.     struct rwindow    *pwindow;/* Pointer to locals and ins. */
  172.     struct fpu    *pfpu;    /* Pointer to FPU register block. */
  173.  
  174. /*
  175.  * fp_emulator simulates FPU and CPU-FPU instructions; reads and writes FPU
  176.  * data registers from image in pfpu.
  177.  */
  178.  
  179. {
  180.     union {
  181.         int        i;
  182.         fp_inst_type    inst;
  183.     }        kluge;
  184.     enum ftt_type    ftt;
  185.  
  186.     fptrapaddr = (char *) pinst;    /* bad inst addr in case we trap */
  187.     _fp_current_pfregs = pfpu;
  188.     _fp_current_read_freg = _fp_read_vfreg;
  189.     _fp_current_write_freg = _fp_write_vfreg;
  190.     ftt = _fp_read_word((caddr_t) pinst, &(kluge.i));
  191.     if (ftt != ftt_none)
  192.         return (ftt);
  193.     if ((kluge.inst.hibits == 2) && ((kluge.inst.op3 == 0x34) || (kluge.inst.op3 == 0x35))) {
  194.         pregs->r_pc = pregs->r_npc;    /* Do not retry emulated
  195.                          * instruction. */
  196.         pregs->r_npc += 4;
  197.         return _fp_fpu_simulator(kluge.inst, (fsr_type *) & (pfpu->fpu_fsr));
  198.     } else
  199.         return _fp_iu_simulator(kluge.inst, pregs, pwindow, pfpu);
  200. }
  201. #ifndef sprite
  202. #include <sys/param.h>
  203. #include <sys/user.h>
  204. #include <sun4/trap.h>
  205.  
  206. /*
  207.  * Handle traps for UNIX.
  208.  */
  209. void
  210. fp_traps(ftt, rp)
  211.     register enum ftt_type ftt;    /* trap type */
  212.     register struct regs *rp;    /* ptr to regs fro trap */
  213. {
  214.     extern void trap();
  215.  
  216.     switch(ftt) {
  217.     case ftt_ieee:
  218.         u.u_code = fptrapcode;
  219.         trap(T_FP_EXCEPTION, rp, fptrapaddr, 0, 0);
  220.         break;
  221.     case ftt_fault:
  222.         trap(T_DATA_FAULT, rp, fptrapaddr, 0, fptraprw);
  223.         break;
  224.     case ftt_alignment:
  225.         trap(T_ALIGNMENT, rp, fptrapaddr, 0, 0);
  226.         break;
  227.     case ftt_unimplemented:
  228.         trap(T_UNIMP_INSTR, rp, fptrapaddr, 0, 0);
  229.         break;
  230.     default:
  231.         /*
  232.          * We don't expect any of the other types here.
  233.          */
  234.         panic("fp_traps: bad ftt");
  235.     }
  236. }
  237. #endif
  238. #endif /* lint */
  239.